package com.wang.just_sql;

import com.wang.utils.DatabaseUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.xml.sax.SAXException;

import javax.sql.DataSource;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JustSql {
    private static VelocityEngine ve = new VelocityEngine();
    private static DataSource dataSource;
    private static Map<String, JustSqlEntity> entityMap;

    // 通用返回值
    public static List<Map<String, Object>> SUCCESS_RESULT = new ArrayList<>();
    public static List<Map<String, Object>> FAIL_RESULT = new ArrayList<>();

    static {
        ve.init();
    }

    public static void InitDatabase(DataSource dataSource, File configFile) throws IOException {
        JustSql.dataSource = dataSource;
        entityMap = JustSql.parse(configFile);
    }

    public static boolean contains(String url) {
        return entityMap.containsKey(url);
    }

    public static List<Map<String, Object>> execute(String url, Map<String, ?> param) throws SQLException {
        return execute(entityMap.get(url), param);
    }

    private static List<Map<String, Object>> execute(JustSqlEntity entity, Map<String, ?> param) throws SQLException {
        VelocityContext context = new VelocityContext(param);
        StringWriter sw = new StringWriter();
        ve.evaluate(context, sw, "", entity.getSqlTemplate());
        System.out.println(sw);
        if(entity.getType().equals("select")) {
            ResultSet rs = dataSource.getConnection().createStatement().executeQuery(sw.toString());
            return DatabaseUtils.INSTANCE.map(rs);
        } else if(entity.getType().equals("update")) {
            int updateCount = dataSource.getConnection().createStatement().executeUpdate(sw.toString());
            return SUCCESS_RESULT;
        } else {
            boolean isSuccess = dataSource.getConnection().createStatement().execute(sw.toString());
            return isSuccess ? SUCCESS_RESULT : FAIL_RESULT;
        }
    }

    private static Map<String, JustSqlEntity> parse(File file) throws IOException {
        Document doc = Jsoup.parse(file, "UTF-8");
        Elements list = doc.body().child(0).children();
        Map<String, JustSqlEntity> map = new HashMap<>();
        for (Element node : list) {
            JustSqlEntity entity = new JustSqlEntity();
            entity.setType(node.nodeName());
            entity.setName(node.attr("name"));
            entity.setUrl(node.attr("url"));
            entity.setSqlTemplate(node.text());
            map.put(entity.getUrl(), entity);
        }
        return map;
    }
}
